﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using School.Entities;
using School.Common;
using School.Accounting.Reports;

namespace School.Accounting
{
    public class Reporting
    {

        private SchoolEntities db = new SchoolEntities();

        public IEnumerable<PaymentOrderReportObject> GetPaymentReport(long number)
        {
            List<PaymentOrderReportObject> pr = new List<PaymentOrderReportObject>();
            var pos = Voucher.GetPaymentOrdersByNumber(number);

            if (pos.Count() == 0)
                return null;

            PaymentOrderReportObject ob;

            var po = pos.First();

            var student = db.TE_Student.Single(y => y.Id == po.Student_Id);
            ob = new PaymentOrderReportObject() { Expense = po.Expense_Name, Number = po.Number, Date = DateTime.Parse(po.Date.ToString()).ToString(), Value = po.Value.ToString(), Student = po.Student_Name, Campus = db.ORG_Campus.Single(x => x.Id == student.Campus_Id).Name, Certificate = db.ORG_Certificate.Single(x => x.Id == student.Certificate_Id).Name, Stage = db.ORG_Stage.Single(x => x.Id == student.Stage_Id).Name, Grade = db.ORG_Grade.Single(x => x.Id == student.Grade_ID).Name };

            pr.Add(ob);

            return pr;
        }

        public IEnumerable<PaymentOrderDiscountsObject> GetDiscountsReport(long number)
        {
            List<PaymentOrderDiscountsObject> pods = new List<PaymentOrderDiscountsObject>();

            var ds = from x in db.ACC_Payment_Order_Discounts where x.Payment_Order_Number == number select x;

            foreach (var d in ds)
            {
                pods.Add(new PaymentOrderDiscountsObject() { Name = d.ACC_Discount.Name, Code = d.ACC_Discount.Code, Type = d.Type, Value = d.Value });
            }

            return pods;
        }

        public IEnumerable<VoucherReportObject> GetVoucherReport(long number)
        {
            var v = db.ACC_Voucher.Single(x => x.Number == number);
            List<VoucherReportObject> rows = new List<VoucherReportObject>();

            VoucherReportObject voucher = new VoucherReportObject()
            {
                Voucher_Number = v.Number,
                Expense_Name = v.ACC_Expense.Name,
                Student_Id = v.Student_Id,
                Student_Name = v.TE_Student.Ar_FirstName + " " + v.TE_Student.Ar_SecondName + " " + v.TE_Student.Ar_ThirdNmae + " " + v.TE_Student.Ar_FourthName,
                Campus_Name = v.TE_Student.ORG_Campus.Name,
                Certitificate_Name = v.TE_Student.ORG_Certificate.Name,
                Stage_Name = v.TE_Student.ORG_Stage.Name,
                Grade_Name = v.TE_Student.ORG_Grade.Name,
                Value = v.Value,
                Date = v.Date,
                TextValue = MoneyToString.NumToStr((double)v.Value)
            };

            rows.Add(voucher);

            return rows;
        }

        public IEnumerable<BusVoucherReportObject> GetBusVoucherReport(long number)
        {
            var v = db.ACC_Voucher.Single(x => x.Number == number);
            var po = db.SRV_Bus_Payment_Order.Single(x => x.Payment_order_num == v.Payment_Order_Number);

            List<BusVoucherReportObject> rows = new List<BusVoucherReportObject>();

            BusVoucherReportObject voucher = new BusVoucherReportObject()
            {
                Voucher_Number = v.Number,
                Expense_Name = v.ACC_Expense.Name,
                Student_Id = v.Student_Id,
                Student_Name = v.TE_Student.Ar_FirstName + " " + v.TE_Student.Ar_SecondName + " " + v.TE_Student.Ar_ThirdNmae + " " + v.TE_Student.Ar_FourthName,
                Campus_Name = v.TE_Student.ORG_Campus.Name,
                Certitificate_Name = v.TE_Student.ORG_Certificate.Name,
                Stage_Name = v.TE_Student.ORG_Stage.Name,
                Grade_Name = v.TE_Student.ORG_Grade.Name,
                Value = v.Value,
                Date = v.Date,
                TextValue = MoneyToString.NumToStr((double)v.Value),
                GoStation = db.SRV_Bus_Station.Single(x=>x.Id == po.Station_Go_Id).Name,
                ReturnStation = db.SRV_Bus_Station.Single(x => x.Id == po.Station_Return_Id).Name
            };

            rows.Add(voucher);

            return rows;
        }

        public IEnumerable<VoucherDiscountsObject> GetDiscounts(long number)
        {
            List<VoucherDiscountsObject> rows = new List<VoucherDiscountsObject>();

            var ds = from x in db.ACC_Voucher_Discount where x.Voucher_Id == number select x;

            foreach (var d in ds)
            {
                rows.Add(new VoucherDiscountsObject() { Code = d.ACC_Discount.Code, Name = d.ACC_Discount.Name, Type = d.Discount_Type, Value = d.Discount_Value });
            }

            return rows;
        }

        public IEnumerable<IncomeReportObject> GetIncome(System.Data.Objects.ObjectQuery<ACC_Voucher> obj)
        {
            List<IncomeReportObject> data = new List<IncomeReportObject>();

            foreach (var x in obj)
            {
                data.Add(new IncomeReportObject() { Number = x.Number.ToString(), Date = x.Date, StundentNumber = x.TE_Student.RegistrationNumber.ToString(), Value = x.Value, StudentName = x.TE_Student.Ar_FirstName + " " + x.TE_Student.Ar_SecondName + " " + x.TE_Student.Ar_ThirdNmae + " " + x.TE_Student.Ar_FourthName, Expense = x.ACC_Expense.Name });
            }

            return data;
        }

        public List<DiscountReportObject> GetDiscounts(List<DiscountReportObject> obj)
        {
            List<DiscountReportObject> data = new List<DiscountReportObject>();

            foreach (var x in obj)
            {
                data.Add(new DiscountReportObject() { Expense = x.Expense, StudentName = x.StudentName, StudentNumber = x.StudentNumber, DiscountValue = x.DiscountValue, DiscountType = x.DiscountType, DiscountName = x.DiscountName, VoucherDate = x.VoucherDate, VoucherNumber = x.VoucherNumber });
            }

            return data;
        }

        public List<ReturnedReportObject> GetReturned(List<ReturnedReportObject> obj)
        {
            List<ReturnedReportObject> data = new List<ReturnedReportObject>();

            foreach (var x in obj)
            {
                data.Add(new ReturnedReportObject() { Expense = x.Expense, StudentName = x.StudentName, StudentNumber = x.StudentNumber, VoucherValue = x.VoucherValue, ReturnedValue = x.ReturnedValue, ReturnedDate = x.ReturnedDate, ReturnedNumber = x.ReturnedNumber, VoucherDate = x.VoucherDate, VoucherNumber = x.VoucherNumber });
            }

            return data;
        }

        public IEnumerable<ReturnedVoucherReportObject> GetReturnedVoucher(long number)
        {
            List<ReturnedVoucherReportObject> rows = new List<ReturnedVoucherReportObject>();

            var rv = from x in db.ACC_Returned_Vouchers where x.Id == number select x;

            foreach (var v in rv)
            {
                rows.Add(new ReturnedVoucherReportObject() { Value = v.Value, Number = v.Id, Campus = v.ACC_Voucher.TE_Student.ORG_Campus.Name, Certificate = v.ACC_Voucher.TE_Student.ORG_Certificate.Name, Stage = v.ACC_Voucher.TE_Student.ORG_Stage.Name, Grade = v.ACC_Voucher.TE_Student.ORG_Grade.Name, Expense = v.ACC_Voucher.ACC_Expense.Name, Student = v.ACC_Voucher.TE_Student.Ar_FirstName + " " + v.ACC_Voucher.TE_Student.Ar_SecondName + " " + v.ACC_Voucher.TE_Student.Ar_ThirdNmae + " " + v.ACC_Voucher.TE_Student.Ar_FourthName, Date = v.Date });
            }

            return rows;
        }

        public IEnumerable<TotalReportValue> GetTotalReportValue(string total)
        {
            List<TotalReportValue> rows = new List<TotalReportValue>();

            rows.Add(new TotalReportValue() { TotalValue = decimal.Parse(total) });

            return rows;
        }

        public IEnumerable<StudentBalance> GetStudentBalance(System.Data.Objects.ObjectQuery<ACC_Student_Balance> obj)
        {
            List<StudentBalance> data = new List<StudentBalance>();

            foreach (var x in obj)
            {
                data.Add(new StudentBalance() { StudentNumber = x.TE_Student.RegistrationNumber != null ? long.Parse(x.TE_Student.RegistrationNumber.ToString()) : 0, Value = x.Value, StudentName = x.TE_Student.Ar_FirstName + " " + x.TE_Student.Ar_SecondName + " " + x.TE_Student.Ar_ThirdNmae + " " + x.TE_Student.Ar_FourthName });
            }

            return data;
        }

        public IEnumerable<IncompleteVoucherObject> GetIncompleteVouchers(List<IncompleteVoucherObject> obj)
        {
            return obj;
        }

        public IEnumerable<PaymentObject> GetPaymentsReport(List<PaymentObject> obj)
        {
            return obj;
        }

        public IEnumerable<ExpenseReport> GetExpenseReport()
        {
            List<ExpenseReport> er = new List<ExpenseReport>();

            var ex = from x in db.ACC_Expense where x.Automatic_With_Services == false select x;

            foreach (var x in ex)
            {
                er.Add(new ExpenseReport() { ExpenseName = x.Name, ExpensePayments = x.ACC_Expense_Payments.Count(), ExpenseTotal = x.ACC_Expense_Payments.Sum(y => y.Value) });
            }

            return er;
        }
    }

    public class ExpenseReport
    {
        public string ExpenseName { get; set; }
        public int ExpensePayments { get; set; }
        public decimal ExpenseTotal { get; set; }
    }
}
